package com.aplink.generic.xmlparser;

import android.content.Context;

import com.aplink.generic.constant.ConfigParameter;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.pojo.xml.TableInfo;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

public class TableInfoParser {
    private static String getTextNodeValue( Node node ) {
        Node child;
        if ( node != null ) {
            if ( node.hasChildNodes() ) {
                child = node.getFirstChild();
                while ( child != null ) {
                    if ( child.getNodeType() == Node.TEXT_NODE ) {
                        return child.getNodeValue();
                    }
                    child = child.getNextSibling();
                }
            }
        }
        return "";
    }

    public static ArrayList<TableInfo> parse( Document doc ) {

        final ArrayList<TableInfo> tableInfoList = new ArrayList<TableInfo>();

        final NodeList nList = doc
                .getElementsByTagName( ConfigParameter.TABLE_STRUCTURE );
        for ( int temp = 0 ; temp < nList.getLength() ; temp++ ) {

            final TableInfo tableInfo = new TableInfo();
            final Node nNode = nList.item( temp );
            String tableId = "";

            // set tableInfo ID
            if ( nNode.hasAttributes() ) {
                final Attr attr = (Attr) nNode.getAttributes().getNamedItem(
                        ConfigParameter.TABLE_ID );
                if ( attr != null ) {
                    tableId = attr.getNodeValue();
                    tableInfo.setTableName( tableId );
                }
            }

            final ArrayList<ObjPropInfo> objPropInfoList = new ArrayList<ObjPropInfo>();

            // set obj_prop tags
            if ( nNode.getNodeType() == Node.ELEMENT_NODE ) {

                final Element element = (Element) nNode;

                // get Obj_prop tags of this node
                final NodeList ObjPropNodes = element
                        .getElementsByTagName( ConfigParameter.TABLE_OBJ_PROP );

                for ( int objIndex = 0 ; objIndex < ObjPropNodes.getLength() ; objIndex++ ) {

                    final Node nObjPropNode = ObjPropNodes.item( objIndex );
                    final ObjPropInfo objPropInfo = new ObjPropInfo();
                    if ( nObjPropNode.getNodeType() == Node.ELEMENT_NODE ) {

                        final Element elementObjPropNode = (Element) nObjPropNode;
                        String content = "";
                        String objClass = "";

                        // get ID of this property
                        NodeList nodes = elementObjPropNode
                                .getElementsByTagName( ConfigParameter.OBJ_CLASS_ID );
                        if ( nodes.getLength() != 0 ) {
                            content = getTextNodeValue( nodes.item( 0 ) );
                            objPropInfo.setObjectMapping( content ); // done
                            objClass = content;
                        }

                        // get ID of this property
                        nodes = elementObjPropNode
                                .getElementsByTagName( ConfigParameter.OBJ_PROP_ID );
                        if ( nodes.getLength() != 0 ) {
                            content = getTextNodeValue( nodes.item( 0 ) );
                            objPropInfo.setObjectProperty( content ); // done
                        }

                        // check isKey
                        final Node nNodeID = nodes.item( 0 );
                        final Element elementchild = (Element) nNodeID;
                        final String iskey = elementchild
                                .getAttribute( ConfigParameter.OBJ_PROP_ISKEY );
                        if ( iskey.compareToIgnoreCase( "Y" ) == 0 ) {
                            objPropInfo.setKey( true ); // done
                        }

                        // check isAuto
                        final String isAuto = elementchild
                                .getAttribute( ConfigParameter.OBJ_PROP_ISAUTO );
                        if ( isAuto.compareToIgnoreCase( "Y" ) == 0 ) {
                            objPropInfo.setIsAuto( true ); // done
                        }

                        // get datatype of this property
                        nodes = elementObjPropNode
                                .getElementsByTagName( ConfigParameter.OBJ_PROP_DATATYPE );
                        if ( nodes.getLength() != 0 ) {
                            content = getTextNodeValue( nodes.item( 0 ) );
                            objPropInfo.setDataType( content ); // done
                        }

                        // get name of this property
                        nodes = elementObjPropNode
                                .getElementsByTagName( ConfigParameter.OBJ_PROP_NAME );
                        if ( nodes.getLength() != 0 ) {
                            content = getTextNodeValue( nodes.item( 0 ) );
                            objPropInfo.setPropName( content ); // done
                        }

                        // we add this objPropInfo into objPropInfoList
                        if ( objClass.equalsIgnoreCase( tableId ) ) {
                            objPropInfoList.add( objPropInfo );
                        }
                    }
                }
            }
            // set objPropInfoList for this table
            tableInfo.setColumnList( objPropInfoList );
            // add this tableInfo into tableInfoList
            tableInfoList.add( tableInfo );
        }

        return tableInfoList;
    }

    public static ArrayList<TableInfo> parserTableStructure(
            Context paramContext, int xmlFileId ) {
        try {
            final Document document = XMLPaserUtil.openDocumentFrom( paramContext,
                    xmlFileId );
            return parse( document );
        } catch ( final ParserConfigurationException e ) {
            e.printStackTrace();
        } catch ( final SAXException e ) {
            e.printStackTrace();
        } catch ( final IOException e ) {
            e.printStackTrace();
        }
        return null;
    }

    public static ArrayList<TableInfo> parserTableStructure(
            Context paramContext, String xmlFileName ) {
        try {
            final Document document = XMLPaserUtil.openDocumentFrom( paramContext,
                    xmlFileName );
            return parse( document );
        } catch ( final ParserConfigurationException e ) {
            e.printStackTrace();
        } catch ( final SAXException e ) {
            e.printStackTrace();
        } catch ( final IOException e ) {
            e.printStackTrace();
        }
        return null;
    }
}
